home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 476-500 / disk_500 / wiconify / wiconsetter.lzh / wInfo2Icon / wInfo2Icon.c < prev    next >
C/C++ Source or Header  |  1991-04-19  |  9KB  |  337 lines

  1. /*
  2.  *  WINFO2ICON      A companion utility to wIconSetter and wIconify.
  3.  *                  wInfo2Icon converts a Workbench .info file into
  4.  *                  an icon file usable by wIconSetter.
  5.  *
  6.  *  Copyright 1990 by Davide P. Cervone, all rights reserved.
  7.  *  You may use this code, provided this copyright notice is kept intact.
  8.  */
  9.  
  10. #include "wInfo2Icon.h"
  11.  
  12. static char *program   = PROGRAM;
  13. static char *copyright = COPYRIGHT;
  14.  
  15. struct IconBase *IconBase;
  16.  
  17. static struct DiskObject *theInfo;      /* Data read from the .info file */
  18. static long IconFile;                   /* the output icon file */
  19. static struct BitMap theBitMap;         /* a bitmap for the image */
  20. static struct BitMap theMaskMap;        /* a bitmap for the mask image */
  21. static int theWidth,theHeight,theDepth; /* size of the image */
  22. static struct TmpRas theTmpRas;         /* needed for FloodFill */
  23.  
  24. static char *InfoName;                  /* name of the info file */
  25. static char *IconName;                  /* name of the icon file */
  26.  
  27. static char *Hex = "0123456789abcdef)!@#$%^&*(ABCDEF";
  28. #define MAXHEX      32
  29. #define MAXLINE     132
  30.  
  31. #define BLT_INVERT  0x50
  32. #define FLOOD_SAME  1
  33.  
  34.  
  35. /*
  36.  *  FreePlanes()
  37.  *
  38.  *  Free each bitplane of the bitmap and free the temporary raster.
  39.  */
  40.  
  41. static void FreePlanes()
  42. {
  43.    short i;
  44.  
  45.    for (i=0; i<theDepth; i++)
  46.    {
  47.       if (theBitMap.Planes[i])
  48.          FreeRaster(theBitMap.Planes[i],theWidth,theHeight);
  49.       theBitMap.Planes[i] = NULL;
  50.    }
  51.    if (theTmpRas.RasPtr) FreeRaster(theTmpRas.RasPtr,theWidth,theHeight);
  52.    theTmpRas.RasPtr = NULL;
  53. }
  54.  
  55.  
  56. /*
  57.  *  DoExit()
  58.  *
  59.  *  General purpose error-exit routine.  Print an error message if one was
  60.  *  supplied (it can have up to three parameters), and then clean up any
  61.  *  memory, libraries, etc. that need to be handled before exiting.
  62.  */
  63.  
  64. void DoExit(s,x1,x2,x3)
  65. char *s, *x1, *x2, *x3;
  66. {
  67.    long status = EXIT_OK;
  68.    
  69.    if (s != NULL)
  70.    {
  71.       printf(s,x1,x2,x3);
  72.       printf("\n");
  73.       status = EXIT_ERROR;
  74.    }
  75.    FreePlanes();
  76.    if (IconFile)        fclose(IconFile);
  77.    if (theInfo)         FreeDiskObject(theInfo);
  78.    if (IntuitionBase)   CloseLibrary(IntuitionBase);
  79.    if (GfxBase)         CloseLibrary(GfxBase);
  80.    if (IconBase)        CloseLibrary(IconBase);
  81.    exit(status);
  82. }
  83.  
  84.  
  85. /*
  86.  *  CheckLibOpen()
  87.  *
  88.  *  Call OpenLibrary() for the specified library, and check that the 
  89.  *  open succeeded.
  90.  */
  91.  
  92. static void CheckLibOpen(lib,name,rev)
  93. APTR *lib;
  94. char *name;
  95. int rev;
  96. {
  97.    extern APTR OpenLibrary();
  98.  
  99.    if ((*lib = OpenLibrary(name,(LONG)rev)) == NULL)
  100.       DoExit("Can't open %s",name);
  101. }
  102.  
  103.  
  104. /*
  105.  *  GetPlanes()
  106.  *
  107.  *  Set the size of the image, but add an extra bitplane (for the mask)
  108.  *  Initialize the BitMaps
  109.  *  Get the bitplanes for the BitMap
  110.  *  Make the mask BitMap share the last bitplane
  111.  *  Get a temporary raster (for FloodFill)
  112.  */
  113.  
  114. static void GetPlanes(w,h,d)
  115. int w,h,d;
  116. {
  117.    short i;
  118.  
  119.    theWidth = w; theHeight = h; theDepth = d+1;
  120.    InitBitMap(&theBitMap,theDepth,w,h);
  121.    InitBitMap(&theMaskMap,1,w,h);
  122.    for (i=0; i<theDepth; i++)
  123.    {
  124.       theBitMap.Planes[i] = AllocRaster(w,h);
  125.       if (theBitMap.Planes[i] == NULL) DoExit("Can't Get BitPlane %d",i);
  126.    }
  127.    theMaskMap.Planes[0] = theBitMap.Planes[d];
  128.    theTmpRas.RasPtr = (UBYTE *)AllocRaster(w,h);
  129.    if (theTmpRas.RasPtr == NULL) DoExit("Can't Get TmpRas for FloodFill");
  130.    theTmpRas.Size   = RASSIZE(theWidth,theHeight);
  131. }
  132.  
  133.  
  134. /*
  135.  *  DoBackFill()
  136.  *
  137.  *  Invert the image's bitmap (so the Mask bitplane becomes all 1's) and flood
  138.  *  the RastPort with 0's starting at the upper left-hand corner.  Since there
  139.  *  is a one pixel border around the actual image data, this does a flood fill
  140.  *  from the outside of the image into the interior.  The Mask bitplane then
  141.  *  has 0's exactly outside the image itself.
  142.  */
  143.  
  144. static void DoBackFill(theRastPort)
  145. struct RastPort *theRastPort;
  146. {
  147.    BltBitMap(theRastPort->BitMap,0,0,theRastPort->BitMap,0,0,
  148.       theWidth,theHeight,BLT_INVERT,0xFF,NULL);
  149.    SetAPen(theRastPort,0L);
  150.    SetDrMd(theRastPort,JAM1);
  151.    Flood(theRastPort,FLOOD_SAME,0,0);
  152. }
  153.  
  154.  
  155. /*
  156.  *  WriteBitMap()
  157.  *
  158.  *  Clip the width to the maximum we can write
  159.  *  For each row in the image
  160.  *    And each column in each row
  161.  *      Get the pen color of the pixel
  162.  *      Store the HEX digit in the line buffer
  163.  *    End the line and print it to the file
  164.  */
  165.  
  166. static void WriteBitMap(theRastPort,Width,Height,x,y)
  167. struct RastPort *theRastPort;
  168. int Width,Height,x,y;
  169. {
  170.    short h,w;
  171.    int pen;
  172.    char Line[MAXLINE];
  173.  
  174.    if (Width > MAXLINE) Width = MAXLINE;
  175.  
  176.    for (h=0; h<Height; h++)
  177.    {
  178.       for (w=0; w<Width; w++)
  179.       {
  180.          pen = ReadPixel(theRastPort,w+x,h+y) % MAXHEX;
  181.          Line[w] = Hex[pen];
  182.       }
  183.       Line[w] = 0;
  184.       fprintf(IconFile,"\n   ");
  185.       fprintf(IconFile,Line);
  186.    }
  187.    fprintf(IconFile,"\n");
  188. }
  189.  
  190.  
  191. /*
  192.  *  WriteImage()
  193.  *
  194.  *  If there is an image to write,
  195.  *    Free any bitplanes that we already got
  196.  *    Get the number of planes we need to write and count the depth
  197.  *    Get the bitplanes for a slightly larger image (leave a border around it)
  198.  *    Set up the RastPort to use the BitMap and TmpRas
  199.  *    Clear the bitmap and temporarily remove the extra bitplane
  200.  *    Draw the image into the prepared bitmap, leaving a 1-pixel border
  201.  *    Write the image to the file
  202.  *    If we are also writing the mask,
  203.  *      Put back the extra bitplane
  204.  *      Do the backfill stuff to get the mask
  205.  *      Write the MASK command
  206.  *      Use the mask bitmap and write the mask to the file
  207.  */
  208.  
  209. static void WriteImage(theImage,MaskIt)
  210. struct Image *theImage;
  211. int MaskIt;
  212. {
  213.    int depth;
  214.    int mask;
  215.    struct RastPort theRastPort;
  216.  
  217.    if (theImage)
  218.    {
  219.       FreePlanes();
  220.       mask = theImage->PlanePick | theImage->PlaneOnOff;
  221.       for (depth=0; mask; depth++) mask >>= 1;
  222.       if (depth > 5) depth = 5;
  223.       GetPlanes(theImage->Width+2,theImage->Height+2,depth);
  224.       InitRastPort(&theRastPort);
  225.       theRastPort.BitMap = &theBitMap;
  226.       theRastPort.TmpRas = &theTmpRas;
  227.       SetRast(&theRastPort,0L); theBitMap.Depth--;
  228.       DrawImage(&theRastPort,theImage,1,1);
  229.       WriteBitMap(&theRastPort,theImage->Width,theImage->Height,1,1);
  230.       if (MaskIt)
  231.       {
  232.          theBitMap.Depth++;
  233.          DoBackFill(&theRastPort);
  234.          fprintf(IconFile,"\nMASK:\n");
  235.          theRastPort.BitMap = &theMaskMap; 
  236.          WriteBitMap(&theRastPort,theImage->Width,theImage->Height,1,1);
  237.       }
  238.    }
  239. }
  240.  
  241.  
  242. /*
  243.  *  WriteIcon()
  244.  *
  245.  *  Get the WB icon's Gadget structure
  246.  *  Write the identification header to the file
  247.  *  If the gadget has an image,
  248.  *    Write the IMAGE command to the file
  249.  *    Write the image itself, and write the mask if it is a BACKFILL icon
  250.  *  Now check the highlight bits:
  251.  *    GADGHIMAGE:
  252.  *      If there is a select image,
  253.  *        Write the SELECT command, and write the image data and mask
  254.  *    GADGHNONE:
  255.  *      If the gadget had an image,
  256.  *        Write it as the select image (this way it looks the same selected
  257.  *        as unselected) and write the mask as well, for good measure
  258.  *        (the WB doesn't do this, but we will, since it's easy)
  259.  *    Don't write anything else for the other highlight types
  260.  *    (we've already taken care of GADGHBACKFILL, and GADGHCOMP is the
  261.  *     default function of wIconify).
  262.  */
  263.  
  264. static void WriteIcon()
  265. {
  266.    struct Gadget *theGadget = &(theInfo->do_Gadget);
  267.    
  268.    fprintf(IconFile,"/*\n *  %s\n *\n",IconName);
  269.    fprintf(IconFile," *  An Icon created by %s\n",program);
  270.    fprintf(IconFile," *  From the Workbench icon %s.info\n",InfoName);
  271.    fprintf(IconFile," */\n");
  272.  
  273.    if ((theGadget->Flags & GADGIMAGE) && theGadget->GadgetRender)
  274.    {
  275.       fprintf(IconFile,"\nIMAGE:\n");
  276.       WriteImage(theGadget->GadgetRender,
  277.          (theGadget->Flags & GADGHIGHBITS) == GADGBACKFILL);
  278.    }
  279.    switch(theGadget->Flags & GADGHIGHBITS)
  280.    {
  281.       case GADGHIMAGE:
  282.          if (theGadget->SelectRender)
  283.          {
  284.             fprintf(IconFile,"\nSELECT:\n");
  285.             WriteImage(theGadget->SelectRender,TRUE);
  286.          }
  287.          break;
  288.  
  289.       case GADGHNONE:
  290.          if ((theGadget->Flags & GADGIMAGE) && theGadget->GadgetRender)
  291.          {
  292.             fprintf(IconFile,"\nSELECT:\n");
  293.             WriteImage(theGadget->GadgetRender,TRUE);
  294.          }
  295.          break;
  296.  
  297.       case GADGBACKFILL:
  298.       case GADGHCOMP:
  299.          break;
  300.    }
  301. }
  302.  
  303.  
  304. /*
  305.  *  main()
  306.  *
  307.  *  If run from the WB, sinply exit
  308.  *  Show the usage if there are not the right number of arguments
  309.  *  Otherwise, get the file names
  310.  *  Open the needed libraries
  311.  *  Get the info from the .info file, if possible
  312.  *  Open the icon file for writing, if possible
  313.  *  Write the icon to the file
  314.  */
  315.  
  316. void main(argc,argv)
  317. int argc;
  318. char **argv;
  319. {
  320.    if (argc == 0) DoExit(NULL);
  321.    if (argc != 3) DoExit("Usage:  %s",USAGE);
  322.    InfoName = argv[1];
  323.    IconName = argv[2];
  324.  
  325.    CheckLibOpen(&IntuitionBase,"intuition.library",INTUITION_REV);
  326.    CheckLibOpen(&GfxBase,"graphics.library",GRAPHICS_REV);
  327.    CheckLibOpen(&IconBase,"icon.library",ICON_REV);
  328.  
  329.    theInfo = GetDiskObject(InfoName);
  330.    if (theInfo == NULL) DoExit("Can't read Info file '%s.info'",InfoName);
  331.    IconFile = fopen(IconName,"w");
  332.    if (IconFile == NULL) DoExit("Can't write Icon file '%s'",IconName);
  333.    WriteIcon();
  334.  
  335.    DoExit(NULL);
  336. }
  337.